﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Interop.Word;
using Microsoft.Office.Tools.Ribbon;
using Rugicon.Outlook;

namespace Rugicon
{
    /// <summary>
    /// This Ribbon shows all emoticons available, from Live Messenger and the user PC, and allows to insert them
    /// in the current e-mail.
    /// </summary>
    public partial class EmoticonsRibbon
    {
        /// <summary>
        /// Instantiates an <see cref="EmoticonsRibbon"/> object.
        /// </summary>
        public EmoticonsRibbon()
            : base(Globals.Factory.GetRibbonFactory())
        {
            InitializeComponent();

            // Fix to prevent crash of the Ribbon Visual Designer
            this.groupEmoticons.Position = this.Factory.RibbonPosition.AfterOfficeId("GroupInsertTables");

            // Set up the gallery
            this.galleryEmoticons.ItemImageSize = new Size(32, 32);
            this.galleryEmoticons.ShowItemLabel = false;
            this.galleryEmoticons.ShowItemSelection = false;
            this.galleryEmoticons.Click += (s, e) =>
            {
                var emoticon = galleryEmoticons.SelectedItem.Tag as Emoticon;
                
                // Check if the reference to the inspector is valid
                var inspector = this.Context as Inspector;
                if (inspector == null)
                    return;

                // Add the emoticon at the current selection start
                var editor = inspector.WordEditor as Document;
                editor.Application.Selection.Range.InlineShapes.AddPicture(emoticon.Filename);
            };

            // Set up the options entry-points
            this.buttonOptions.Click += (s, e) =>
                {
                    ShowOptions();
                };

            this.groupEmoticons.DialogLauncherClick += (s, e) =>
                {
                    ShowOptions();
                };

            // Creates the ribbon for the custom emoticons
            ReloadEmoticons();

            // Reload emoticons when some are added at runtime
            Emoticons.EmoticonsChanged += (s, e) =>
                {
                    ReloadEmoticons();
                };

            // Very important! Allows to reuse the ribbon for all inspectors.
            // Other case, it will not work after first time is shown.
            // This is because the names of the ribbon controls are not set,
            // so each time a new name is used, but the ribbon can't change
            // after is initialized the first time, so fails.
            this.Global = true;
        }

        /// <summary>
        /// Shows the Options form.
        /// </summary>
        public void ShowOptions()
        {
            new OptionsForm().ShowDialog();
        }

        /// <summary>
        /// Invalidates the emoticon UI and adds a <see cref="RibbonButton"/> into the Live Emoticons tab
        /// for each custom emoticon in Live Messenger. Can be called many times and after the ribbon UI is loaded.
        /// </summary>
        public void ReloadEmoticons()
        {
            this.galleryEmoticons.Items.Clear();
            foreach (Emoticon emoticon in Emoticons.GetAllEmoticons())
            {
                var button = CreateEmoticonDropDownItem(emoticon);
                this.galleryEmoticons.Items.Add(button);
            }
        }

        /// <summary>
        /// Creates a <see cref="RibbonButton"/> for the given emoticon.
        /// </summary>
        /// <param name="emoticon">The emoticon info.</param>
        /// <returns>An instance of <see cref="RibbonButton"/> representing the emoticon.</returns>
        private RibbonButton CreateEmoticonButton(Emoticon emoticon)
        {
            var button = this.Factory.CreateRibbonButton();

            button.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeRegular;
            button.ShowImage = true;
            button.ShowLabel = false;
            button.Image = Image.FromFile(emoticon.Filename);

            button.Click += (sender, e) =>
                {
                    // Check if the reference to the inspector is valid
                    var inspector = this.Context as Inspector;
                    if (inspector == null)
                        return;

                    // Add the emoticon at the current selection start
                    var editor = inspector.WordEditor as Document;
                    editor.Application.Selection.Range.InlineShapes.AddPicture(emoticon.Filename);
                };

            return button;
        }

        /// <summary>
        /// Creates a <see cref="RibbonDropDownItem"/> for the given emoticon.
        /// </summary>
        /// <param name="emoticon">The emoticon info.</param>
        /// <returns>An instance of <see cref="RibbonDropDownItem"/> representing the emoticon.</returns>
        private RibbonDropDownItem CreateEmoticonDropDownItem(Emoticon emoticon)
        {
            var dropDownItem = this.Factory.CreateRibbonDropDownItem();

            dropDownItem.Image = Image.FromFile(emoticon.Filename);
            dropDownItem.Tag = emoticon;

            return dropDownItem;
        }
    }
}
